using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace OWED.Document
{
    public class AddTag: ChangeAtom
    {
        XmlNode child;

        //position of the child in the children list after the add
        int position;

        public AddTag(AbsolutePath addPath, XmlNode newChild, int childPosition)
        {
            path = addPath;
            child = newChild;
            position = childPosition;
        }

        public override void Apply(XmlDocument document)
        {
            XmlNode node = path.getNode(document);
            if (node.HasChildNodes)
            {
                XmlNode curChild = node.FirstChild;
                for (int i = 1; i < position; i++)
                {
                    curChild = curChild.NextSibling;
                }
                node.InsertBefore(child, curChild);

            }
            else
            {
                node.AppendChild(child);
            }
        }

        public XmlNode Node { get { return child; } }

        public override void Reverse(XmlDocument document)
        {
            int index = 0;
            for (; index < child.ParentNode.ChildNodes.Count; ++index)
                if (child.ParentNode.ChildNodes[index].Equals(child))
                    break;
            //I have to do my own search, because XmlNode has a screwy collection...
            AbsolutePath p = new AbsolutePath(path, child.Name, index);
            (new DeleteTag(p, child)).Apply(document);
        }

        public override string Serialize()
        {
            XmlDocument doc = new XmlDocument();
            doc.AppendChild(doc.CreateElement("root"));
            doc.FirstChild.AppendChild(doc.CreateElement("path"));
            doc.FirstChild.FirstChild.AppendChild(doc.CreateTextNode(path.ToString()));
            doc.FirstChild.AppendChild(doc.CreateElement("node"));
            doc.FirstChild.ChildNodes[1].AppendChild(doc.ImportNode(child, false));
            doc.FirstChild.ChildNodes[1].AppendChild(doc.CreateElement("pos"));
            XmlAttribute attr = doc.CreateAttribute("n");
            attr.Value = position.ToString();
            doc.SelectSingleNode("/root/node/pos").Attributes.Append(attr);

            return ChangeAtom.AtomType(this) + doc.OuterXml;
        }

        public static new ChangeAtom DeSerialize(String atom)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(atom);
            XmlNode node = doc.SelectSingleNode("/root/node").FirstChild;
            AbsolutePath path = new AbsolutePath(doc.SelectSingleNode("/root/path").FirstChild.Value);
            int pos = int.Parse(doc.SelectSingleNode("/root/node/pos").Attributes[0].Value);

            return new AddTag(path, node, pos);
        }
    }
}
